using System.Globalization;
using System.Web.UI;
using Quiki.ElementFormatters;
using Quiki.ExpressionParsers;

namespace Quiki.Templates
{
    public class TableOfContentsTemplate : IWikiTemplate
    {
        public const string TemplateId = "toc";

        public string TemplateName
        {
            get { return TemplateId; }
        }

        public void Expand(WikiTemplateElement element, WikiDocument document, DocumentGraph documentGraph)
        {
        }

        public void Format(WikiTemplateElement element, HtmlFormatterContext context)
        {
            WikiTextElement rootElement = context.Document.RootElement;

            context.Writer.AddAttribute(HtmlTextWriterAttribute.Class, "toc");
            context.Writer.AddAttribute(HtmlTextWriterAttribute.Id, "toc");
            context.Writer.RenderBeginTag(HtmlTextWriterTag.Table);

            context.Writer.RenderBeginTag(HtmlTextWriterTag.Tbody);
            context.Writer.RenderBeginTag(HtmlTextWriterTag.Tr);
            context.Writer.RenderBeginTag(HtmlTextWriterTag.Td);

            RenderTocTitle(context);
            RenderToc (rootElement, context);

            context.Writer.RenderEndTag();
            context.Writer.RenderEndTag();
            context.Writer.RenderEndTag();
            context.Writer.RenderEndTag();
        }

        private static void RenderTocTitle(HtmlFormatterContext context)
        {
            context.Writer.AddAttribute(HtmlTextWriterAttribute.Id, "toctitle");
            context.Writer.RenderBeginTag(HtmlTextWriterTag.Div);
            context.Writer.RenderBeginTag(HtmlTextWriterTag.H2);
            context.Writer.Write("Contents");
            context.Writer.RenderEndTag ();
            context.Writer.RenderEndTag ();
        }

        private static void RenderToc(WikiTextElement element, HtmlFormatterContext context)
        {
            int currentLevel = 1;
            foreach (WikiTextElement childElement in element.ChildElements)
            {
                if (childElement.ElementType != WikiTextElementType.Heading)
                    continue;

                if (childElement.Level < 2 || childElement.Level > 4)
                    continue;

                while (currentLevel < childElement.Level)
                {
                    context.Writer.RenderBeginTag(HtmlTextWriterTag.Ul);
                    currentLevel++;
                }

                while (currentLevel > childElement.Level)
                {
                    context.Writer.RenderEndTag();
                    currentLevel--;
                }

                string tocClass = string.Format (
                    CultureInfo.InvariantCulture,
                    "toclevel-{0}",
                    currentLevel);

                context.Writer.AddAttribute (HtmlTextWriterAttribute.Class, tocClass);
                context.Writer.RenderBeginTag(HtmlTextWriterTag.Li);

                context.Writer.AddAttribute(
                    HtmlTextWriterAttribute.Href, 
                    '#' + HeaderElementFormatter.FormatHeaderAnchorLink(childElement));
                context.Writer.RenderBeginTag(HtmlTextWriterTag.A);
                context.Writer.Write(childElement.Text);
                context.Writer.RenderEndTag();
                context.Writer.RenderEndTag();
            }

            while (currentLevel > 1)
            {
                context.Writer.RenderEndTag ();
                currentLevel--;
            }
        }
    }
}